/**
 * @author Jason Pratt
 */

package edu.cmu.cs.stage3.alice.authoringtool.util;

import edu.cmu.cs.stage3.alice.authoringtool.AuthoringTool;
import edu.cmu.cs.stage3.alice.authoringtool.AuthoringToolResources;
import edu.cmu.cs.stage3.alice.authoringtool.datatransfer.CallToUserDefinedQuestionPrototypeReferenceTransferable;
import edu.cmu.cs.stage3.alice.authoringtool.datatransfer.CallToUserDefinedResponsePrototypeReferenceTransferable;
import edu.cmu.cs.stage3.alice.authoringtool.datatransfer.ElementReferenceTransferable;
import edu.cmu.cs.stage3.alice.authoringtool.datatransfer.ObjectArrayPropertyItemTransferable;
import edu.cmu.cs.stage3.alice.authoringtool.util.event.DnDManagerListener;
import edu.cmu.cs.stage3.swing.DialogManager;

public class TrashComponent extends javax.swing.JPanel implements java.awt.dnd.DropTargetListener {

 protected javax.swing.ImageIcon trashOpenIcon = AuthoringToolResources.getIconForValue( "trashOpen" );
 protected javax.swing.ImageIcon trashClosedIcon = AuthoringToolResources.getIconForValue( "trashClosed" );
 protected javax.swing.JLabel trashLabel = new javax.swing.JLabel( trashClosedIcon );
 protected AuthoringTool authoringTool;
 protected boolean paintDropPotential = false;
 protected DropPotentialFeedbackListener dropPotentialFeedbackListener = new DropPotentialFeedbackListener();
 protected boolean beingDroppedOn = false;

 public TrashComponent (AuthoringTool authoringTool) {
  this.authoringTool = authoringTool;
  setLayout( new java.awt.BorderLayout() );
  setOpaque( false );
  add( trashLabel, java.awt.BorderLayout.CENTER );
  this.setDropTarget( new java.awt.dnd.DropTarget( this, this ) );
  trashLabel.setDropTarget( new java.awt.dnd.DropTarget( trashLabel, this ) );
  edu.cmu.cs.stage3.alice.authoringtool.util.DnDManager.addListener( dropPotentialFeedbackListener );

  setToolTipText( "<html><font face=arial size=-1>Trash<p><p>Drag and drop tiles here to delete them.</font></html>" );

  addMouseListener( new edu.cmu.cs.stage3.alice.authoringtool.util.CustomMouseAdapter() {
   //Rem @Override
   public void singleClickResponse( java.awt.event.MouseEvent ev) {
    DialogManager.showMessageDialog( TrashComponent.this.getToolTipText() );
   }
  } );
 }

 //Rem @Override
 public java.awt.Dimension getMaximumSize () {
  return trashLabel.getMaximumSize();
 }

 // Called by: 
 //Rem @Override
 public void paintComponent (java.awt.Graphics g) {
  // System.out.println("\n\nTrashComponent.java: paintComponent(Graphics): paintDropPotential="+paintDropPotential);
  if (paintDropPotential) {
   //try{String str="";System.out.println(str.charAt(3));}catch(Exception e){e.printStackTrace();}
   //   trashLabel.setEnabled( true );
   java.awt.Dimension size = getSize();
   if (beingDroppedOn) {
    g.setColor( AuthoringToolResources.getColor( "dndHighlight2" ) );
   } else {
    g.setColor( AuthoringToolResources.getColor( "dndHighlight" ) );
    }
   g.drawRect( 0, 0, size.width - 1, size.height - 1 );
   g.drawRect( 1, 1, size.width - 3, size.height - 3 );
   //  } else {
   //   trashLabel.setEnabled( false );
  }
  super.paintComponent( g );
 }

 ////////////////////////////////////
 // DropTargetListener interface
 ////////////////////////////////////

 //TODO: remove duplicated code
 protected boolean checkTransferable (java.awt.datatransfer.Transferable transferable) {
  //if (AuthoringToolResources.safeIsDataFlavorSupported(transferable, ElementReferenceTransferable.elementReferenceFlavor ) ||
  //    AuthoringToolResources.safeIsDataFlavorSupported(transferable, ObjectArrayPropertyItemTransferable.objectArrayPropertyItemFlavor ) ||
  //    AuthoringToolResources.safeIsDataFlavorSupported(transferable, CallToUserDefinedResponsePrototypeReferenceTransferable.callToUserDefinedResponsePrototypeReferenceFlavor ) ||
  //    AuthoringToolResources.safeIsDataFlavorSupported(transferable, CallToUserDefinedQuestionPrototypeReferenceTransferable.callToUserDefinedQuestionPrototypeReferenceFlavor ) )
  // if (1==1) { System.err.println("TrashComponent.java: forcao resposta true"); return true; }
//System.out.println("TrashComponent.java: "+transferable);
  boolean b1 = false, b2 = false, b3 = false, b4 = false;
  try {
    b1 = AuthoringToolResources.safeIsDataFlavorSupported(transferable, ElementReferenceTransferable.elementReferenceFlavor );
  } catch (Exception e) { System.err.println("Error: TrashComponent.java: "+e.toString()); }
  try {
    //AuthoringToolResources.getReferenceFlavorForClass(ObjectArrayPropertyItemTransferable.objectArrayPropertyItemFlavor); //LOB
    b2 = AuthoringToolResources.safeIsDataFlavorSupported(transferable, ObjectArrayPropertyItemTransferable.objectArrayPropertyItemFlavor );
  } catch (Exception e) { System.err.println("Error: TrashComponent.java: "+e.toString()); }
  try {
    b3 = AuthoringToolResources.safeIsDataFlavorSupported(transferable, CallToUserDefinedResponsePrototypeReferenceTransferable.callToUserDefinedResponsePrototypeReferenceFlavor );
  } catch (Exception e) { System.err.println("Error: TrashComponent.java: "+e.toString()); }
  try {
    // b4 = AuthoringToolResources.safeIsDataFlavorSupported(transferable, CallToUserDefinedQuestionPrototypeReferenceTransferable.callToUserDefinedQuestionPrototypeReferenceFlavor );
    b4 = AuthoringToolResources.safeIsDataFlavorSupported(transferable,
                                CallToUserDefinedQuestionPrototypeReferenceTransferable.callToUserDefinedQuestionPrototypeReferenceFlavor );
  } catch (Exception e) { System.err.println("Error: TrashComponent.java: "+e.toString()); }
  if (b1 || b2 || b3 || b4) {
     return true;
  } else {
     return false;
     }
  }

 // When draging any object and pass mouse over the "trash basket"
 protected boolean checkDrag (java.awt.dnd.DropTargetDragEvent dtde) {
/*boolean
 b1 = AuthoringToolResources.safeIsDataFlavorSupported(dtde, ElementReferenceTransferable.elementReferenceFlavor),
 b2 = AuthoringToolResources.safeIsDataFlavorSupported(dtde, ObjectArrayPropertyItemTransferable.objectArrayPropertyItemFlavor),
 b3 = AuthoringToolResources.safeIsDataFlavorSupported(dtde, CallToUserDefinedQuestionPrototypeReferenceTransferable.callToUserDefinedQuestionPrototypeReferenceFlavor),
 b4 = AuthoringToolResources.safeIsDataFlavorSupported(dtde, CallToUserDefinedResponsePrototypeReferenceTransferable.callToUserDefinedResponsePrototypeReferenceFlavor);
System.out.println("\n\nTrashComponent.java: checkDrag(DropTargetDragEvent): entrei... b1="+b1+", b2="+b2+", b3="+b3+", b4="+b4+"");
*/
  if (AuthoringToolResources.safeIsDataFlavorSupported(dtde, ElementReferenceTransferable.elementReferenceFlavor ) ||
    AuthoringToolResources.safeIsDataFlavorSupported(dtde, ObjectArrayPropertyItemTransferable.objectArrayPropertyItemFlavor ) ||
    AuthoringToolResources.safeIsDataFlavorSupported(dtde, CallToUserDefinedQuestionPrototypeReferenceTransferable.callToUserDefinedQuestionPrototypeReferenceFlavor ) ||
    AuthoringToolResources.safeIsDataFlavorSupported(dtde, CallToUserDefinedResponsePrototypeReferenceTransferable.callToUserDefinedResponsePrototypeReferenceFlavor )) {
   dtde.acceptDrag( java.awt.dnd.DnDConstants.ACTION_MOVE );
   trashLabel.setIcon( trashOpenIcon );
   //System.out.println("TrashComponent.java: checkDrag(DropTargetDragEvent): OK");
   return true;
  } else {
   //System.out.println("TrashComponent.java: checkDrag(DropTargetDragEvent): NAO");
   dtde.rejectDrag();
   return false;
   }
  }

 public void dragEnter (java.awt.dnd.DropTargetDragEvent dtde) {
System.out.println("\n\nTrashComponent.java: dragEnter(DropTargeDragEvent): checkDrag="+checkDrag(dtde));
  if (checkDrag(dtde)) {
   beingDroppedOn = true;
   repaint();
   }
  }

 public void dragExit (java.awt.dnd.DropTargetEvent dte) {
  if (beingDroppedOn) {
   beingDroppedOn = false;
   repaint();
   }
  trashLabel.setIcon( trashClosedIcon );
  }

 public void dragOver (java.awt.dnd.DropTargetDragEvent dtde) {
  if (! checkDrag( dtde )) {
   beingDroppedOn = false;
   repaint();
   }
  }

 public void drop (java.awt.dnd.DropTargetDropEvent dtde) {
  try {
    // 'element' could be 'edu.cmu.cs.stage3.alice.core.response.PropertyAnimation'
//System.out.println("TrashComponent.java: drop(java.awt.dnd.DropTargetDropEvent): "+edu.cmu.cs.stage3.util.StrUtilities.getComponentName(ElementReferenceTransferable.elementReferenceFlavor));
   if (AuthoringToolResources.safeIsDataFlavorSupported(dtde, ElementReferenceTransferable.elementReferenceFlavor )) {
    dtde.acceptDrop( java.awt.dnd.DnDConstants.ACTION_MOVE );
    java.awt.datatransfer.Transferable transferable = dtde.getTransferable();
    edu.cmu.cs.stage3.alice.core.Element element = (edu.cmu.cs.stage3.alice.core.Element)transferable.getTransferData( ElementReferenceTransferable.elementReferenceFlavor );
    //HACK
    // if (authoringTool!=AuthoringTool.getInstance()) System.out.println("TrashComponent.java: drop(...): authoringTool ERRO");
    // else System.out.println("TrashComponent.java: drop(...): authoringTool OK");
    edu.cmu.cs.stage3.alice.authoringtool.util.ElementPopupUtilities.DeleteRunnable deleteRunnable = new edu.cmu.cs.stage3.alice.authoringtool.util.ElementPopupUtilities.DeleteRunnable( element ); //L , authoringTool );
//System.out.println("TrashComponent.java: drop(java.awt.dnd.DropTargetDropEvent): "+edu.cmu.cs.stage3.util.StrUtilities.getComponentName(ElementReferenceTransferable.elementReferenceFlavor)+": "+
//edu.cmu.cs.stage3.util.StrUtilities.getComponentName(element));
    deleteRunnable.run();
    dtde.dropComplete( true );
   } else if (AuthoringToolResources.safeIsDataFlavorSupported(dtde, CallToUserDefinedResponsePrototypeReferenceTransferable.callToUserDefinedResponsePrototypeReferenceFlavor )) {
    dtde.acceptDrop( java.awt.dnd.DnDConstants.ACTION_MOVE );
    java.awt.datatransfer.Transferable transferable = dtde.getTransferable();
    edu.cmu.cs.stage3.alice.authoringtool.util.CallToUserDefinedResponsePrototype callToUserDefinedResponsePrototype = (edu.cmu.cs.stage3.alice.authoringtool.util.CallToUserDefinedResponsePrototype)transferable.getTransferData( CallToUserDefinedResponsePrototypeReferenceTransferable.callToUserDefinedResponsePrototypeReferenceFlavor );
    //HACK
    edu.cmu.cs.stage3.alice.authoringtool.util.ElementPopupUtilities.DeleteRunnable deleteRunnable = new edu.cmu.cs.stage3.alice.authoringtool.util.ElementPopupUtilities.DeleteRunnable( callToUserDefinedResponsePrototype.getActualResponse() ); //L, authoringTool );
    deleteRunnable.run();
    dtde.dropComplete( true );
   } else if (AuthoringToolResources.safeIsDataFlavorSupported(dtde, CallToUserDefinedQuestionPrototypeReferenceTransferable.callToUserDefinedQuestionPrototypeReferenceFlavor )) {
    dtde.acceptDrop( java.awt.dnd.DnDConstants.ACTION_MOVE );
    java.awt.datatransfer.Transferable transferable = dtde.getTransferable();
    edu.cmu.cs.stage3.alice.authoringtool.util.CallToUserDefinedQuestionPrototype callToUserDefinedQuestionPrototype = (edu.cmu.cs.stage3.alice.authoringtool.util.CallToUserDefinedQuestionPrototype)transferable.getTransferData( CallToUserDefinedQuestionPrototypeReferenceTransferable.callToUserDefinedQuestionPrototypeReferenceFlavor );
    //HACK
    edu.cmu.cs.stage3.alice.authoringtool.util.ElementPopupUtilities.DeleteRunnable deleteRunnable = new edu.cmu.cs.stage3.alice.authoringtool.util.ElementPopupUtilities.DeleteRunnable( callToUserDefinedQuestionPrototype.getActualQuestion() ); //L, authoringTool );
    deleteRunnable.run();
    dtde.dropComplete( true );
   } else if (AuthoringToolResources.safeIsDataFlavorSupported(dtde, ObjectArrayPropertyItemTransferable.objectArrayPropertyItemFlavor )) {
    dtde.acceptDrop( java.awt.dnd.DnDConstants.ACTION_MOVE );
    java.awt.datatransfer.Transferable transferable = dtde.getTransferable();
    ObjectArrayPropertyItem item = (ObjectArrayPropertyItem)transferable.getTransferData( ObjectArrayPropertyItemTransferable.objectArrayPropertyItemFlavor );
    item.objectArrayProperty.remove( item.getIndex() );
    dtde.dropComplete( true );
   } else {
    dtde.rejectDrop();
    dtde.dropComplete( false );
    }
  } catch( java.awt.datatransfer.UnsupportedFlavorException e) {
   AuthoringTool.getInstance().showErrorDialog( "Drop didn't work: bad flavor", e );
   dtde.dropComplete( false );
  } catch( java.io.IOException e) {
   AuthoringTool.getInstance().showErrorDialog( "Drop didn't work: IOException", e );
   dtde.dropComplete( false );
  } catch( Throwable t) {
   AuthoringTool.getInstance().showErrorDialog( "Drop didn't work.", t );
   dtde.dropComplete( false );
   }
  trashLabel.setIcon( trashClosedIcon );
  }

 public void dropActionChanged (java.awt.dnd.DropTargetDragEvent dtde) {
  checkDrag( dtde );
 }

 protected class DropPotentialFeedbackListener implements DnDManagerListener {
  private void doCheck () {
   java.awt.datatransfer.Transferable transferable = edu.cmu.cs.stage3.alice.authoringtool.util.DnDManager.getCurrentTransferable();
   boolean transferableHasPotential = checkTransferable( transferable );
   if (TrashComponent.this.paintDropPotential != transferableHasPotential) {
    TrashComponent.this.paintDropPotential = transferableHasPotential;
    TrashComponent.this.repaint();
   }
  }

  public void dragGestureRecognized (java.awt.dnd.DragGestureEvent dge) {
   // do nothing for the gesture, wait until dragStarted
  }

  public void dragStarted() {
   doCheck();
  }

  public void dragEnter (java.awt.dnd.DragSourceDragEvent dsde) {
   doCheck();
  }

  public void dragExit (java.awt.dnd.DragSourceEvent dse) {
   doCheck();
  }

  public void dragOver (java.awt.dnd.DragSourceDragEvent dsde) {
   //don't check here
  }

  public void dropActionChanged (java.awt.dnd.DragSourceDragEvent dsde) {
   doCheck();
  }

  public void dragDropEnd (java.awt.dnd.DragSourceDropEvent dsde) {
   TrashComponent.this.paintDropPotential = false;
   TrashComponent.this.repaint();
  }
 }

}
